package com.spring.theory.bean.beanFactoryPostProcessor;

import static com.spring.theory.constant.GeneralConstant.LOG_INFO;

import com.spring.theory.bean.beanFactoryPostProcessor.model.Config;
import com.spring.theory.bean.beanFactoryPostProcessor.postProcessor.ComponentScanPostProcessor;
import com.spring.theory.bean.beanFactoryPostProcessor.postProcessor.MapperPostProcessor;
import com.spring.theory.bean.beanFactoryPostProcessor.postProcessor.TestBeanPostFactoryProcessor;

import java.util.Arrays;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionCustomizer;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;

/**
 * 阅读3-1
 * BeanFactoryPostProcessor bean工厂后处理器
 * - 针对bean定义的处理器
 *
 * @author H
 * @version 1.0
 * @date 2023-12-25 16:34
 */
@Slf4j
public class TestBeanFactoryPostProcessor {

    @SneakyThrows
    public static void main(String[] args) {
        GenericApplicationContext context = new GenericApplicationContext();
        context.registerBean("config", Config.class);

        //test1(context);
        test2(context);

        context.refresh();

        log.info(LOG_INFO + "容器内存在的bean");
        Arrays.stream(context.getBeanDefinitionNames()).forEach(log::info);
        log.info(LOG_INFO);

        context.close();

    }

    /**
     * bean工厂后处理器添加
     */
    private static void test1(GenericApplicationContext context) {
        /**
         * 解析@ComponentScan、@Bean、@Import、@ImportResource等注解
         */
        context.registerBean(ConfigurationClassPostProcessor.class);
        /**
         * MapperScannerConfigurer 用于扫描注解指定包目录下的所有接口，把他们注册到bean工厂里面
         *  @MapperScan底层和它一个原理 ClassPathMapperScanner
         */
        context.registerBean(MapperScannerConfigurer.class,
                new BeanDefinitionCustomizer() {
                    @Override
                    public void customize(BeanDefinition t) {
                        t.getPropertyValues().add("basePackage", "com.spring.theory.service.bean.beanFactoryPostProcessor.model");
                    }
                });
    }

    /**
     * 自定义bean工厂后处理器
     */
    private static void test2(GenericApplicationContext context) {
        /**
         * 2.自定义注册beanFactory处理器 @Component
         */
        context.registerBean(ComponentScanPostProcessor.class);
        /**
         * 3.自定义注册beanFactory处理器 @Bean
         */
        context.registerBean(TestBeanPostFactoryProcessor.class);
        /**
         * 4.自定义注册beanFactory处理器 @Mapper
         */
        context.registerBean(MapperPostProcessor.class);
    }


}
